package com.childenglish.mapper;

import com.childenglish.entity.FileInfo;
import org.apache.ibatis.annotations.*;

import java.util.Date;
import java.util.List;

@Mapper
public interface FileInfoMapper {

    @Insert("INSERT INTO file_info (file_md5, file_name, original_name, file_path, file_size, file_type, mime_type, " +
            "chunked, total_chunks, chunk_size, upload_time, complete_time, status, upload_user, description, review_status, review_reason, reviewer, review_time) " +
            "VALUES (#{fileMd5}, #{fileName}, #{originalName}, #{filePath}, #{fileSize}, #{fileType}, #{mimeType}, " +
            "#{chunked}, #{totalChunks}, #{chunkSize}, #{uploadTime}, #{completeTime}, #{status}, #{uploadUser}, #{description}, " +
            "#{reviewStatus}, #{reviewReason}, #{reviewer}, #{reviewTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(FileInfo fileInfo);

    @Update("UPDATE file_info SET file_path = #{filePath}, file_size = #{fileSize}, status = #{status}, " +
            "complete_time = #{completeTime}, description = #{description}, review_status = #{reviewStatus}, " +
            "review_reason = #{reviewReason}, reviewer = #{reviewer}, review_time = #{reviewTime} WHERE id = #{id}")
    int update(FileInfo fileInfo);

    @Delete("DELETE FROM file_info WHERE file_md5 = #{fileMd5}")
    int deleteByFileMd5(String fileMd5);

    @Delete("DELETE FROM file_info WHERE file_name = #{fileName}")
    int deleteByFileName(String fileName);
    
    @Delete("DELETE FROM file_info WHERE original_name = #{originalName}")
    int deleteByOriginalName(String originalName);

    @Select("SELECT * FROM file_info WHERE file_md5 = #{fileMd5}")
    @Results(id = "fileInfoMap", value = {
            @Result(property = "id", column = "id"),
            @Result(property = "fileMd5", column = "file_md5"),
            @Result(property = "fileName", column = "file_name"),
            @Result(property = "originalName", column = "original_name"),
            @Result(property = "filePath", column = "file_path"),
            @Result(property = "fileSize", column = "file_size"),
            @Result(property = "fileType", column = "file_type"),
            @Result(property = "mimeType", column = "mime_type"),
            @Result(property = "chunked", column = "chunked"),
            @Result(property = "totalChunks", column = "total_chunks"),
            @Result(property = "chunkSize", column = "chunk_size"),
            @Result(property = "uploadTime", column = "upload_time"),
            @Result(property = "completeTime", column = "complete_time"),
            @Result(property = "status", column = "status"),
            @Result(property = "uploadUser", column = "upload_user"),
            @Result(property = "description", column = "description"),
            @Result(property = "reviewStatus", column = "review_status"),
            @Result(property = "reviewReason", column = "review_reason"),
            @Result(property = "reviewer", column = "reviewer"),
            @Result(property = "reviewTime", column = "review_time")
    })
    FileInfo selectByFileMd5(String fileMd5);

    @Select("SELECT * FROM file_info WHERE file_name = #{fileName}")
    @ResultMap("fileInfoMap")
    FileInfo selectByFileName(String fileName);

    @Select("SELECT * FROM file_info WHERE status = #{status} ORDER BY upload_time DESC")
    @ResultMap("fileInfoMap")
    List<FileInfo> selectByStatus(Integer status);

    @Select("SELECT * FROM file_info WHERE upload_time < #{expireTime} AND status != 2")
    @ResultMap("fileInfoMap")
    List<FileInfo> selectExpiredFiles(Long expireTime);

    @Update("UPDATE file_info SET status = #{status}, complete_time = #{completeTime} WHERE file_md5 = #{fileMd5}")
    int updateStatusByFileMd5(@Param("fileMd5") String fileMd5, @Param("status") Integer status,
                              @Param("completeTime") Long completeTime);

    @Select("SELECT COUNT(*) FROM file_info WHERE file_md5 = #{fileMd5}")
    int existsByFileMd5(String fileMd5);

    @Select("<script>" +
            "SELECT * FROM file_info WHERE 1=1 " +
            "<if test='reviewStatus != null'>" +
            "  <if test='reviewStatus == 0'> AND (review_status = 0 OR review_status IS NULL) </if>" +
            "  <if test='reviewStatus != 0'> AND review_status = #{reviewStatus} </if>" +
            "</if>" +
            "<if test='fileType != null and fileType != \"\"'> AND file_type = #{fileType} </if>" +
            "ORDER BY upload_time DESC" +
            "</script>")
    @ResultMap("fileInfoMap")
    List<FileInfo> selectByReviewStatus(@Param("reviewStatus") Integer reviewStatus, @Param("fileType") String fileType);
    
    /**
     * 查询所有文件（不限制审核状态）
     */
    @Select("<script>" +
            "SELECT * FROM file_info WHERE 1=1 " +
            "<if test='fileType != null and fileType != \"\"'> AND file_type = #{fileType} </if>" +
            "ORDER BY upload_time DESC" +
            "</script>")
    @ResultMap("fileInfoMap")
    List<FileInfo> selectAll(@Param("fileType") String fileType);

    @Update("UPDATE file_info SET review_status = #{reviewStatus}, review_reason = #{reviewReason}, " +
            "reviewer = #{reviewer}, review_time = #{reviewTime} WHERE file_name = #{fileName}")
    int updateReviewStatus(@Param("fileName") String fileName, @Param("reviewStatus") Integer reviewStatus,
                          @Param("reviewReason") String reviewReason, @Param("reviewer") String reviewer,
                          @Param("reviewTime") Date reviewTime);

    @Update("UPDATE file_info SET file_type = #{fileType}, review_status = #{reviewStatus} WHERE file_name = #{fileName}")
    int updateFileTypeAndReviewStatus(@Param("fileName") String fileName, 
                                     @Param("fileType") String fileType,
                                     @Param("reviewStatus") Integer reviewStatus);
}